Micron Document
Fox's Git Mirrors

Node / rns-mirrors / Reticulum-Go.git / files / docs / en / security.md

Displaying Rendered • View rawDownload

docs/en/security.md 61af5556362c8bdf7c09a1c01bc84f81629f281b (61af5556) Text, 12.60 KB

Security

Purpose

This page summarizes security practices for Reticulum-Go. The repository root SECURITY.md remains the authoritative source for reporting contacts and detailed CI paths. Cryptography covers algorithms and key handling.

Reporting vulnerabilities

Report security issues privately before public disclosure.

┌────────────────┬──────────────────────────────────┐
│ Channel │ Contact │
├────────────────┼──────────────────────────────────┤
│ Reticulum LXMF │ f489752fbef161c64d65e385a4e9fc74 │
│ Email │ T383838security@quad4.io
└────────────────┴──────────────────────────────────┘

Include enough detail to reproduce the issue: component, expected behavior, actual behavior, and environment.

Threat model (practical summary)

Reticulum-Go assumes:

• Attackers can send arbitrary packets on configured interfaces
• Long-term identity keys must remain confidential
• Operators configure IFAC passphrases and network names as shared secrets for interface segments
• Host OS hardening is the operator responsibility outside the daemon sandbox

The stack provides cryptographic authentication and encryption per the Reticulum protocol. It does not replace firewall policy, physical security, or application-level authorization.

Runtime sandbox

The T383838reticulum-go daemon calls T383838sandbox.Apply from T383838pkg/sandbox after config load, transport start, shared-instance attach, and Control API bind. Privileged initialization and listeners complete first so FreeBSD CapEnter and OpenBSD pledge do not block those sockets.

Default: T383838enable_sandbox = yes in T383838[reticulum]. Set T383838enable_sandbox = no to disable (not recommended for production).

On Linux, enable_seccomp defaults to yes when the sandbox is enabled. Set T383838enable_seccomp = no to skip the seccomp filter. Install prefers process-wide T383838SECCOMP_FILTER_FLAG_TSYNC, then falls back to per-OS-thread install (T383838AllThreadsSyscall), then T383838prctl(PR_SET_SECCOMP) on kernels without the seccomp syscall. Any remaining failure soft-fails so older kernels and constrained environments keep running.

┌──────────────┬─────────────────────────────────────────────────┬─────────────────────────────────┐
│ OS │ Mechanism │ Effect │
├──────────────┼─────────────────────────────────────────────────┼─────────────────────────────────┤
│ Linux │ Landlock, seccomp-bpf, PRSETNONEWPRIVS, rlimits │ Whitelists config and storage … │
│ OpenBSD │ unveil, pledge │ Restricts visible paths and sy… │
│ FreeBSD │ cap_enter, rlimits │ Capability mode after resource… │
│ Darwin │ rlimits │ Memory, FD, core dump, stack, … │
│ Windows │ Job object │ Limits breakaway, processes, w… │
│ Other / WASM │ no-op │ Logs unsupported, continues │
└──────────────┴─────────────────────────────────────────────────┴─────────────────────────────────┘

Landlock requires Linux kernel 5.13 or newer. Older kernels skip Landlock gracefully where possible. Seccomp soft-fails on install error or T383838ENOSYS.

The WASM build (T383838reticulum-wasm) does not use this sandbox. It relies on the browser or host runtime instead.

Sandboxing is defense in depth. It is not a substitute for a MicroVM or strong host isolation. It does not fix weak passphrases, leaked identity files, or misconfigured interfaces.

Cryptography

All protocol crypto details: Cryptography.

Application code should use T383838pkg/cryptography and T383838pkg/identity. IFAC configuration is part of interface security, not a substitute for link encryption.

Supply chain

Vendored dependencies. Third-party source is committed in T383838vendor/. Ordinary builds use T383838GOFLAGS=-mod=vendor and T383838GOPROXY=off so compile time does not fetch modules from the network.

CI security scans. GitHub Actions runs Gosec, govulncheck, and Trivy on pushes and pull requests to T383838master/T383838dev. CodeQL covers Go, JavaScript/TypeScript, Python, and Actions workflows. Pull requests also run T383838dependency-review.yml. Trivy is installed from a pinned release with SHA256 verification (T383838scripts/ci/setup-trivy.sh).

Reproducibility. CI includes a reproducibility check (T383838task reproducibility).

Actions pinning. Third-party actions are pinned to full commit SHAs. Dependabot proposes weekly Action updates (T383838.github/dependabot.yml).

Tree integrity. Root file T383838reticulum-go.rsm is an rnid signed message embedding SHA-256 hashes of tracked files (excluding T383838vendor/ trees). CI verifies signer e46112d44649266d71fe2193e00a4710 and rechecks bytes at job start and end (T383838make tree-rsm-verify).

Releases

Tagged releases publish from T383838.github/workflows/publish.yml on GitHub Actions.

Each release asset has a cosign attestation bundle (T383838*.cosign.bundle) signed with the project key. Public key: T383838cosign.pub in the repository.

Verify:

T282828
sh scripts/ci/verify-release-attestation.sh PATH/TO/blob PATH/TO/blob.cosign.bundle

SHA256 listings in release notes are an informal backup. Prefer cosign verification.

SBOMs (SPDX and CycloneDX) are attached to tagged releases via Trivy (T383838task sbom).

Static analysis in development

┌─────────────┬─────────────────────────────────────────────┐
│ Tool │ Purpose │
├─────────────┼─────────────────────────────────────────────┤
│ Gosec │ Go security linter │
│ govulncheck │ Go vulnerability database with reachability │
│ Trivy │ Filesystem and dependency scan │
│ revive │ Style and lint (T383838make lint) │
└─────────────┴─────────────────────────────────────────────┘

Run locally:

T282828
make vulncheck
make lint

Full check target:

T282828
make check

Logging and secrets

• Log destination supports stderr, file, both, syslog, journald, and combinations such as T383838syslog+stderr. Set logfile when using a file path.
• High debug levels may print packet hex. Use loglevel 4 or lower in production unless diagnosing an incident.
• rpc_key protects the control API and shared-instance RPC. Generate with cryptographic random bytes. Do not commit keys to version control.
• T383838identity_backend = secretservice keeps identity private blobs in the desktop keyring (Secret Service) instead of plaintext files. Requires an unlocked session collection.
• T383838identity_backend = keyring stores the same blobs in the Linux kernel keyring (no D-Bus), suitable for systemd units. See Identity and destinations for threat coverage.
• Identity private keys are held in locked memory when the OS allows (T383838pkg/securemem). This is defense in depth, not a substitute for disk encryption or HSM signing.

DoS protection (local IDS/IPS)

Go-only. Config key T383838dos_protection in T383838[reticulum] (default T383838auto). Implementation: T383838pkg/protect.

This is node-local overload control. It sheds work on this process so floods, accept storms, crypto spam, handshake spam, resource pile-ups, and memory pressure do not freeze the daemon. It is not a network-wide IDS and does not stop Sybil join storms across the mesh (for example mass fake peers on an anonymity overlay). Pair it with IFAC, careful public-face exposure, and operator policy.

┌─────────┬────────────────────────────────────────────────────────────────────────────────────────┐
│ Mode │ Effect │
├─────────┼────────────────────────────────────────────────────────────────────────────────────────┤
│ off │ No gates │
│ detect │ Observe and warn only │
│ prevent │ Observe, warn, and block or shed │
│ auto │ Learn baselines quietly, persist them, arm prevent, relearn on interface set change o… │
└─────────┴────────────────────────────────────────────────────────────────────────────────────────┘

Adaptive baselines use EWMA of once-per-second peak pps/bps. Flood samples are ignored while learning so an attack cannot become the quiet baseline. Persistence path: T383838storage/dos_protect.mpack.

Trips emit rate-limited stdout warnings and increment T383838dos_* health counters. Full key reference and gate table: Configuration. Tests: Development and testing.

Handler pool exhaustion always sheds packets (never sync-dispatches on the ingress thread). Priority shedding prefers established link and proof traffic over announce-class floods when slightly over the adaptive trip line, but that leniency still counts toward the interface's cool-down accounting so sustained abuse of it still escalates instead of running indefinitely.

Memory pressure shedding (heap watermark) enforces immediately in T383838prevent and in T383838auto, regardless of learning phase. It does not wait for T383838auto to arm, since heap exhaustion is a safety valve rather than a flood-learning signal. Explicit T383838detect still never blocks, matching its observe-only contract.

Rate, byte, and cool-down accounting run per remote peer as well as per interface. A single sender sharing a listener (a busy TCP/QUIC/VSOCK/I2P accept loop, a UDP socket, or the HTTPS long-poll transport) is capped at half of the interface's effective trip line before its own sub-bucket sheds, so one hostile peer cannot exhaust the whole interface budget and cool down every other peer on it. Peer sub-buckets are bounded and idle ones are pruned so the mitigation cannot itself become a memory-growth vector.

On FreeBSD with sandbox enabled, T383838SIGHUP re-execs the daemon so T383838CapEnter does not block config reload. Other platforms keep in-process T383838ReloadInterfaces.

Linux Landlock or seccomp soft-fail emits T383838WARNING: sandbox soft-unavailable mechanism=... on stdout once per mechanism per 30 seconds.

Local mesh health (observe only)

Reticulum-Go keeps node-local integrity and link-health counters in T383838pkg/health. They stay on this node. Nothing is flooded to the mesh or sent to a cloud collector.

Counters increment at existing drop and fail sites (IFAC verify, link HMAC, unpack errors, announce signature rejects, link proof rejects, request timestamp skew, blackhole hits, link stale closes, resource stalls, NIC flaps, duplicate announces, suppressed PATH_RESPONSE answers, duplicate path requests, missing announce cache for path answers, and unknown-iface link relay drops). Accept and reject behavior is unchanged.

Operators see the numbers through:

┌─────────────────────────────────────┬────────────────────────────────────────────────────────────┐
│ Surface │ What you get │
├─────────────────────────────────────┼────────────────────────────────────────────────────────────┤
│ T383838reticulum-go status │ Per-interface integrity totals and fail rate when non-zero │
│ T383838reticulum-go status -json │ Same fields in JSON (ifacfail, hmacfail, integrityfailrat… │
│ T383838reticulum-go snapshot (rgosnap) │ Paths, active links, and full transport health JSON inclu… │
│ T383838reticulum-go slow │ Scored findings such as integrityburst, authpressure, lin… │
│ Control API T383838GET /v1/status │ Integrity and drop fields on each interface object │
│ Shared-instance RPC interface_stats │ Same msgpack keys (Go daemon only populates them) │
└─────────────────────────────────────┴────────────────────────────────────────────────────────────┘

Scoring prefers fail ratios and bitrate-aware thresholds. High latency alone on a low-bitrate radio is not treated as critical. There is no auto blackhole or auto interface offline in this release. The operator decides whether to adjust IFAC keys, enable ingress control, blackhole an identity, or take an interface down.

See CLI utilities for status and slow, packet-debug for dump and snapshot, and Control API for HTTP fields.

Control API exposure

The control API binds to T383838127.0.0.1 by default. It is disabled unless T383838enable_control_api = yes. Do not expose it to untrusted networks without additional TLS and auth layers (not provided by this package).

BZ2 bomb limits

Resource and buffer decompression enforce size limits aligned with Python 1.1.9 to resist compression bombs. The T383838rgosh stream path also caps decompressed channel chunks (T383838MaxDecompressed) and rejects oversize inflate attempts.

rgosh remote shell

T383838reticulum-go sh / rgosh authenticates sessions with Reticulum link identity allowlists. Deny tears the link down and never starts a remote process. Per-session config copies prevent argv pollution across clients. Prefer explicit T383838-a allowlists over T383838-n. Use T383838-C when the listener must run a fixed command only. T383838--compat speaks Python rnsh for interop but keeps the same hardened auth FSM.

Hop field validation (RNS 1.3.8)

Python RNS 1.3.8 rejects packets whose hop byte is T383838>= PATHFINDER_M (128) during unpack. Reticulum-Go mirrors that in T383838pkg/packet.Unpack. Values 128 through 255 are dropped before transport processing.

Link establishment also records expected_hops on both initiator and responder. Initiator LRPROOF acceptance requires the proof hop count to match (or T383838expected_hops == PATHFINDER_M when the path length was unknown at link creation), matching Python Transport pending-link gating.

Related documents

Configuration for sandbox, control API, and dos_protection keys
CLI utilities for status and slow health findings
Packet debug for dump, snapshot, and Wireshark
SECURITY.md full policy text
Compatibility for RNS 1.4.2 interop
Package map for T383838pkg/protect

Served by rngit 1.5.2 - Generated in 0.03s